package message

import (
	"bytes"
	"encoding/binary"
	"errors"
	"zinxtcp/utils"
)

type PackHeader struct {
	Id      uint32 //消息的ID
	DataLen uint32 //消息的长度
}

func NewPackHeader(id uint32) *PackHeader {
	return &PackHeader{
		Id: id,
	}
}

func (ph *PackHeader) ParseHeader(binaryData []byte) error {
	//创建一个从输入二进制数据的ioReader
	dataBuff := bytes.NewReader(binaryData)
	//读dataLen
	if err := binary.Read(dataBuff, binary.LittleEndian, &ph.DataLen); err != nil {
		return err
	}
	//读msgID
	if err := binary.Read(dataBuff, binary.LittleEndian, &ph.Id); err != nil {
		return err
	}
	//判断dataLen的长度是否超出我们允许的最大包长度
	if utils.GlobalObject.MaxPacketSize > 0 && ph.DataLen > utils.GlobalObject.MaxPacketSize {
		return errors.New("Too large msg data recieved")
	}
	//这里只需要把head的数据拆包出来就可以了，然后再通过head的长度，再从conn读取一次数据
	return nil
}

//获取包头长度方法
func (ph *PackHeader) GetHeadLen() uint32 {
	//Id uint32(4字节) +  DataLen uint32(4字节)
	return 8
}

//获取消息数据段长度
func (ph *PackHeader) GetDataLen() uint32 {
	return ph.DataLen
}

//获取消息ID
func (ph *PackHeader) GetMsgType() uint32 {
	return ph.Id
}

//将包头压缩成二进制码
func (ph *PackHeader) EncodeHeader() ([]byte, error) {
	//创建一个存放bytes字节的缓冲
	dataBuff := bytes.NewBuffer([]byte{})
	//写dataLen
	if err := binary.Write(dataBuff, binary.LittleEndian, ph.GetDataLen()); err != nil {
		return nil, err
	}
	//写msgID
	if err := binary.Write(dataBuff, binary.LittleEndian, ph.GetMsgType()); err != nil {
		return nil, err
	}
	return dataBuff.Bytes(), nil
}

//设置消息数据段长度
func (ph *PackHeader) SetDataLen(len uint32) {
	ph.DataLen = len
}

//设计消息ID
func (ph *PackHeader) SetMsgType(msgType uint32) {
	ph.Id = msgType
}
